<template>
    <div class="exam-list">
        <el-card>
            <el-table :data="list" style="width: 100%">
                <el-table-column prop="id" label="ID" width="60" />
                <el-table-column prop="title" label="试卷标题" />
                <el-table-column prop="question_count" label="题数" width="80" />
                <el-table-column prop="total_score" label="总分" width="80" />
                <el-table-column prop="duration" label="时长(分钟)" width="100" />
                <el-table-column label="操作" width="180">
                    <template #default="scope">
                        <el-button size="small" type="primary" @click="startExam(scope.row)">开始考试</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>
        <el-dialog v-model="showExam" title="考试答题" width="900px">
            <div v-if="examPaper">
                <div style="margin-bottom: 8px">
                    试卷：{{ examPaper.title }}（共{{ questions.length }}题，总分{{ examPaper.total_score }}，时长{{ examPaper.duration }}分钟）
                </div>
                    <div style="text-align:center; margin-bottom:6px">
                        <div style="font-size:20px; font-weight:700">{{ examPaper.title }}</div>
                        <div style="font-size:12px; color:#666; margin-top:4px">{{ examPaper.description }}</div>
                        <div style="margin-top:6px; font-size:13px">共{{ questions.length }}题， 总分{{ examPaper.total_score }}， 时长{{ examPaper.duration }} 分钟</div>
                    </div>
                    <div style="text-align:center; margin-bottom:8px">
                        <span v-if="remainingSeconds>0">倒计时：<b>{{ formatTime(remainingSeconds) }}</b></span>
                        <span v-else style="color:#c00"><b>时间已到，不能提交</b></span>
                    </div>
                <el-form ref="examForm">
                    <div v-for="(q, i) in questions" :key="q.id" style="margin-bottom: 18px">
                        <div>
                            <b>{{ i + 1 }}. [{{ typeMap[q.type] || q.type }}]</b> {{ q.content }}
                        </div>
                        <div style="margin-top: 8px">
                            <template v-if="q.type === 'single'">
                                <el-radio-group v-model="answers[q.id]">
                                    <el-radio v-for="opt in optionsList(q)" :key="opt.label" :label="opt.label" style="display: block; padding: 8px">
                                        <span style="font-weight: 600; margin-right: 8px">{{ opt.label }}.</span>{{ opt.text }}
                                    </el-radio>
                                </el-radio-group>
                            </template>
                            <template v-else-if="q.type === 'multi'">
                                <el-checkbox-group v-model="answers[q.id]">
                                    <el-checkbox
                                        v-for="opt in optionsList(q)"
                                        :key="opt.label"
                                        :label="opt.label"
                                        style="display: block; padding: 8px"
                                    >
                                        <span style="font-weight: 600; margin-right: 8px">{{ opt.label }}.</span>{{ opt.text }}
                                    </el-checkbox>
                                </el-checkbox-group>
                            </template>
                            <template v-else-if="q.type === 'judge'">
                                <el-radio-group v-model="answers[q.id]">
                                    <el-radio label="A">A. 对</el-radio>
                                    <el-radio label="B">B. 错</el-radio>
                                </el-radio-group>
                            </template>
                            <template v-else-if="q.type === 'blank'">
                                <el-input v-model="answers[q.id]" placeholder="请填写答案" />
                            </template>
                            <template v-else-if="q.type === 'short'">
                                <el-input v-model="answers[q.id]" type="textarea" placeholder="请作答" />
                            </template>
                        </div>
                    </div>
                </el-form>
                    <el-button type="primary" @click="submitExam" :disabled="remainingSeconds<=0">提交试卷</el-button>
            </div>
        </el-dialog>
        <el-dialog v-model="showResult" title="考试结果" width="700px">
            <div v-if="result">
                <div>
                    得分：<b>{{ result.score }}</b>
                </div>
                <el-button @click="viewDetail">查看答题详情</el-button>
            </div>
        </el-dialog>
        <el-dialog v-model="showDetail" title="答题详情" width="900px">
            <div v-if="detail">
                <div>试卷：{{ detail.paper.title }}</div>
                <div v-for="(q, i) in detail.questions" :key="q.id" style="margin-bottom: 12px">
                    <div>
                        <b>{{ i + 1 }}. [{{ typeMap[q.type] || q.type }}]</b> {{ q.content }}
                    </div>
                    <div>你的答案：{{ getAnswer(q.id) }}</div>
                    <div>得分：{{ getScore(q.id) }}</div>
                    <div v-if="q.analysis">解析：{{ q.analysis }}</div>
                </div>
            </div>
        </el-dialog>
    </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import request from '/@/utils/request'
import { useRoute } from 'vue-router'

const list = ref([])
const showExam = ref(false)
const examPaper = ref(null)
const questions = ref([])
const answers = reactive({})
const userPaperId = ref(0)
const remainingSeconds = ref(0)
let timerId = null
const showResult = ref(false)
const result = ref(null)
const showDetail = ref(false)
const detail = ref(null)
const typeMap = { single: '单选', multi: '多选', judge: '判断', blank: '填空', short: '简答' }

function getList() {
    request.get('/api/exam/paperList').then((res) => {
        if (res.code === 1) {
            list.value = res.data
        }
    })
}
function startExam(row) {
    request.post('/api/exam/start/paper_id/' + row.id).then((res) => {
        if (res.code === 1) {
            const st = res.data.start_time
            userPaperId.value = res.data.user_paper_id
            request.get('/api/exam/paperDetail/id/' + row.id).then((r2) => {
                if (r2.code === 1) {
                    examPaper.value = r2.data.paper
                    questions.value = r2.data.questions
                    // reset and initialize answers per question
                    Object.keys(answers).forEach((k) => delete answers[k])
                    questions.value.forEach((q) => {
                        if (q.type === 'multi') {
                            answers[q.id] = []
                        } else {
                            answers[q.id] = ''
                        }
                    })
                    showExam.value = true
                    // initialize remainingSeconds from server start_time when provided
                    if (st && examPaper.value && examPaper.value.duration) {
                        const allowed = parseInt(st) + parseInt(examPaper.value.duration) * 60
                        remainingSeconds.value = Math.max(0, allowed - Math.floor(Date.now() / 1000))
                        startTimer()
                    } else {
                        startTimer()
                    }
                }
            })
        }
    })
}

// normalize options for rendering: returns [{label:'A',text:'...'}, ...]
function optionsList(q) {
    if (!q) return []
    const opts = q.options || []
    // if array
    if (Array.isArray(opts)) {
        return opts.map((t, i) => ({ label: String.fromCharCode(65 + i), text: t }))
    }
    // if object with letter keys
    if (typeof opts === 'object') {
        return Object.keys(opts)
            .sort()
            .map((k) => ({ label: k.toUpperCase(), text: opts[k] }))
    }
    return []
}
function submitExam() {
    // guard submit by remainingSeconds
    if (remainingSeconds.value <= 0) {
        ElMessage.error('考试时间已到，不能提交')
        return
    }
    // stop timer to avoid race
    if (timerId) {
        clearInterval(timerId)
        timerId = null
    }

    const arr = questions.value.map((q) => {
        let ans = answers[q.id]
        if (q.type === 'single') {
            // ans is letter
        } else if (q.type === 'multi') {
            // ans may be array of letters or texts; ensure letters
            if (Array.isArray(ans)) {
                ans = ans
                    .map((a) => {
                        if (typeof a === 'string' && a.length === 1 && /[A-Za-z]/.test(a)) return a.toUpperCase()
                        // otherwise find index by text
                        const idx = (q.options || []).indexOf(a)
                        return idx >= 0 ? String.fromCharCode(65 + idx) : a
                    })
                    .join(',')
            }
        } else if (q.type === 'judge') {
            // already A/B
        } else {
            // blank/short keep original
        }
        return { question_id: q.id, type: q.type, answer: ans }
    })
    request.post('/api/exam/submit', { user_paper_id: userPaperId.value, answers: arr }).then((res) => {
        if (res.code === 1) {
            result.value = res.data
            showExam.value = false
            showResult.value = true
        } else {
            ElMessage.error(res.msg)
        }
    })
}
function viewDetail() {
    request.get('/api/exam/myPaperDetail/user_paper_id/' + userPaperId.value).then((res) => {
        if (res.code === 1) {
            detail.value = res.data
            showResult.value = false
            showDetail.value = true
        }
    })
}
function getAnswer(qid) {
    if (!detail.value) return ''
    let ans = (detail.value.answers || []).find((a) => a.question_id === qid)
    if (!ans) return ''
    // ans.answer might be JSON array, comma separated letters, single letter, or text
    let a = ans.answer
    try {
        const maybe = JSON.parse(a)
        if (Array.isArray(maybe)) return maybe.map((m) => formatLetter(m, qid)).join(', ')
    } catch {}
    // comma separated letters
    if (typeof a === 'string' && a.indexOf(',') !== -1) {
        return a
            .split(',')
            .map((s) => formatLetter(s.trim(), qid))
            .join(', ')
    }
    return formatLetter(a, qid) || a
}

function formatLetter(letter, qid) {
    if (!letter) return ''
    letter = ('' + letter).toUpperCase()
    const q = (detail.value.questions || []).find((x) => x.id === qid)
    if (!q) return letter
    const idx = letter.charCodeAt(0) - 65
    const text = (q.options || [])[idx]
    return text ? letter + '. ' + text : letter
}
function getScore(qid) {
    if (!detail.value) return ''
    let ans = (detail.value.answers || []).find((a) => a.question_id === qid)
    return ans ? ans.score : ''
}
onMounted(getList)

// route param handling: support opening exam by query (?user_paper_id=...&paper_id=...)
const route = useRoute()
onMounted(() => {
    const upid = route.query.user_paper_id || route.query.view_user_paper_id
    const pid = route.query.paper_id
    if (upid && pid && !route.query.view_user_paper_id) {
        // auto-open the exam: fetch myPaperDetail to obtain start_time
        userPaperId.value = upid
        request.get('/api/exam/myPaperDetail/user_paper_id/' + upid).then((res) => {
            if (res.code === 1) {
                // server returns paper info and answers
                examPaper.value = res.data.paper
                // load question list from paperDetail to ensure full question data
                request.get('/api/exam/paperDetail/id/' + pid).then((r2) => {
                    if (r2.code === 1) {
                        questions.value = r2.data.questions
                        Object.keys(answers).forEach((k) => delete answers[k])
                        questions.value.forEach((q) => {
                            if (q.type === 'multi') answers[q.id] = []
                            else answers[q.id] = ''
                        })
                        showExam.value = true
                        // compute remainingSeconds using server start_time if available
                        const st = res.data.paper.start_time || res.data.paper.start_time
                        if (st && examPaper.value.duration) {
                            const allowed = parseInt(st) + parseInt(examPaper.value.duration) * 60
                            remainingSeconds.value = Math.max(0, allowed - Math.floor(Date.now() / 1000))
                        }
                        startTimer()
                    }
                })
            }
        })
    } else if (route.query.view_user_paper_id) {
        // view record directly
        const id = route.query.view_user_paper_id
        request.get('/api/exam/myPaperDetail/user_paper_id/' + id).then((res) => {
            if (res.code === 1) {
                detail.value = res.data
                showDetail.value = true
            }
        })
    }
})

function startTimer() {
    // clear existing
    if (timerId) {
        clearInterval(timerId)
        timerId = null
    }
    remainingSeconds.value = 0
    if (!examPaper.value || !examPaper.value.duration) return
    // compute remaining seconds from server start_time if available; else use duration
    // we don't have server side start_time here, assume full duration on client start
    remainingSeconds.value = parseInt(examPaper.value.duration) * 60
    timerId = setInterval(() => {
        remainingSeconds.value -= 1
        if (remainingSeconds.value <= 0) {
            if (timerId) {
                clearInterval(timerId)
                timerId = null
            }
        }
    }, 1000)
}

function formatTime(sec) {
    sec = Math.max(0, parseInt(sec) || 0)
    const m = String(Math.floor(sec / 60)).padStart(2, '0')
    const s = String(sec % 60).padStart(2, '0')
    return `${m}:${s}`
}

// (submit guard merged into main submitExam)
</script>

<style scoped>
.exam-list {
    max-width: 900px;
    margin: 0 auto;
}
</style>
